package rpg.manager
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;

	import rpg.Utils.Log;
	import rpg.Utils.StringUtil;
	import rpg.Utils.Val;
	import rpg.animation.Animation;
	import rpg.animation.AnimationDescription;
	import rpg.animation.AvatarActionDescription;
	import rpg.animation.AvatarAnimation;
	import rpg.animation.AvatarDescription;
	import rpg.animation.ComposedAnimation;
	import rpg.animation.Frame;
	import rpg.data.ResData;
	import rpg.resource.PreLoad;
	import rpg.resource.Resource;
	import rpg.resource.Resources;
	import rpg.resource.SWFResource;

	public class AnimationManager
	{
		private static var instance : AnimationManager;
		/**
		 * 动画数据描述
		 */
		private var animationsDescription : Dictionary;
		/**
		 * 人物动作数据描述
		 */
		private var avatarDescription : Dictionary;
		/**
		 * 角色默认形象信息
		 */
		private var defaultHeroConfig : Dictionary;
		/**
		 * 加载器
		 */
		private var resources : Resources;

		private var dataManager : DataManager;

		private var gm : GameManager;

		public function AnimationManager()
		{

		}

		/**
		 * 初始化
		 *
		 */
		private function init() : void
		{
			this.gm = GameManager.getInstance();
			this.dataManager = DataManager.getInstance();
			this.resources = Resources.getInstance();
			this.animationsDescription = new Dictionary();
			this.avatarDescription = new Dictionary();
			this.parseHeroConfig();
		}

		/**
		 * 单列
		 * @return
		 *
		 */
		public static function getInstance() : AnimationManager
		{
			if(instance == null)
			{
				instance = new AnimationManager();
				instance.init();
			}
			return instance;
		}

		/**
		 * 解析角色默认形象信息
		 *
		 */
		private function parseHeroConfig() : void
		{
			var xml : XML = resources.getXml("heros");
			this.defaultHeroConfig = new Dictionary();
			for each(var config : XML in xml.profession)
			{
				var heroConfig : Object = {};
				var data : XML = config.hero.avatar[0];
				heroConfig.id = String(config.@id);
				heroConfig.name = String(data.@id);
				heroConfig.armLightName = String(data.@armLightName);
				heroConfig.bodyEquipment = String(data.@bodyEquipment);
				heroConfig.rightHandEquipment = String(data.@rightHandEquipment);
				heroConfig.attachmentEquipment = String(data.@attachmentEquipment);
				heroConfig.parts = [heroConfig.bodyEquipment , heroConfig.rightHandEquipment , heroConfig.attachmentEquipment];
				defaultHeroConfig[heroConfig.name] = heroConfig;
			}
		}

		public function createAnimation(animationID : String) : Animation
		{
			var animationDescription : AnimationDescription = getAnimationDescription(animationID);
			var animation : Animation = new Animation(animationID);
			animation.createAnimationFrame(animationDescription);
			return animation;
		}

		/**
		 * 创建一个人物的所有动作动画
		 * "单手近战" , "单手一连击" , "死亡" , "跳跃" , "移动" , "战斗站立" , "坐下" , "坐骑移动" , "坐骑战斗站立"
		 * 8个方向
		 *
		 */
		public function createAvatarAnimation(avatarDes : AvatarDescription , parts : Array) : Dictionary
		{

			var id : String;
			var animations : Array;
			var animation : AvatarAnimation;
			var animationDes : AnimationDescription;
			var actionsDirAnimation : Dictionary = new Dictionary();
			var isCompose : Boolean = parts.length > 1; //是否需要合成部件
			parts.reverse();
			parts = sortPart(parts , avatarDes); //排序
			var composedParts : Array = crateComposedParts(avatarDes , parts);
			for each(var avatarActionDes : AvatarActionDescription in avatarDes.actionsDescription)
			{
				var animationDirs : Dictionary = new Dictionary();
				for each(var dir : int in avatarActionDes.dirs)
				{
					id = avatarDes.name + avatarActionDes.actionName + dir;
					if(isCompose)
						animations = [];
					for each(var composedPart : String in composedParts)
					{
						animation = new AvatarAnimation(composedPart + "/" + avatarActionDes.actionName + dir);
						animationDes = getAnimationDescription(animation.id);
						animation.createAnimationFrame(animationDes);
						animation.avatarActionID = composedPart + "/" + avatarActionDes.actionName;
						animation.avatarActionDes = avatarActionDes;
						if(isCompose)
							animations.push(animation);
					}
					if(isCompose)
					{
						animation = new ComposedAnimation("composed" + id , animations , gm.modelBmd , animationDes.durations , avatarActionDes.frameCount,avatarDes.centerX , avatarDes.centerY);
					
					}
					animationDirs[dir] = animation;
				}
				actionsDirAnimation[avatarActionDes.actionName] = animationDirs;
			}
			return actionsDirAnimation;
		}

		/**
		 * 部件排序
		 *
		 */
		private function sortPart(parts : Array , avatarDes : AvatarDescription) : Array
		{
			var newParts : Array = [];
			var len : int = parts.length;
			var partsType : Array = [];
			var i : int;
			for(i = 0 ; i < len ; i += 1)
			{
				partsType[i] = avatarDes.getPartType(parts[i]);
			}

			for each(var partType : String in avatarDes.animationPartTypes)
			{
				var index : int = partsType.indexOf(partType);
				if(index != -1)
				{
					newParts.push(parts[index]);
				}
			}
			return newParts;
		}

		/**
		 * 返回需要组合的部件名称 如:角色1/右手装备/单手武器11号
		 * @param avatarDes
		 * @param parts
		 * @return
		 *
		 */
		private function crateComposedParts(avatarDes : AvatarDescription , parts : Array) : Array
		{
			var len : int = parts.length;
			var composedParts : Array = [];
			for(var i : int = 0 ; i < len ; i++)
			{
				var partsType : String = avatarDes.getPartType(parts[i]);
				var partID : String = StringUtil.concatStr("/" , avatarDes.name , partsType , parts[i]);
				composedParts.push(partID);
			}
			return composedParts;
		}

		/**
		 * 获得角色默认形象信息
		 * @param roleName
		 * @return
		 *
		 */
		public function getDefaultHeroConfig(roleName : String) : Object
		{
			return defaultHeroConfig[roleName];
		}

		/**
		 * 获得一个人物动作描述信息
		 * @param roleId
		 * @return
		 *
		 */
		public function getAvatarDescription(roleID : String) : AvatarDescription
		{
			if(avatarDescription[roleID] == null)
			{
				var xml : XML = resources.getXml(roleID);
				var avatarDesc : AvatarDescription = new AvatarDescription(xml);
				for each(var animationXML : XML in xml.animations.animation)
				{
					var des : AnimationDescription = new AnimationDescription(animationXML);
					animationsDescription[des.id] = des;
				}
				avatarDescription[roleID] = avatarDesc;
			}
			return avatarDescription[roleID];
		}

		/**
		 * 获得一组动画描述信息
		 * @return
		 *
		 */
		public function getAnimationDescription(id : String) : AnimationDescription
		{
			return animationsDescription[id];
		}

		/**
		 * 解析特效xml,转换成AnimationDescription
		 * @param xml
		 *
		 */
		public function parseEffectDescription(xml : XML) : void
		{
			for each(var effectXml : XML in xml.animation)
			{
				var animationDes : AnimationDescription = new AnimationDescription(effectXml);
				animationsDescription[animationDes.id] = animationDes;
			}
		}

	}

}